<template>
  <div 
    class="home"
    @dragover.prevent="handleDragOver"
    @dragleave.prevent="handleDragLeave"
    @drop.prevent="handleDrop"
    @mousedown="startBoxSelection"
    @mousemove="updateBoxSelection"
    @mouseup="endBoxSelection"
    @contextmenu.prevent="handleEmptyAreaContextMenu"
  >
    <!-- 拖拽上传提示遮罩 -->
    <div v-if="isDragging" class="drag-overlay">
      <el-icon size="64"><Upload /></el-icon>
      <p>释放鼠标上传文件</p>
    </div>

    <!-- 修改选择框的定位 -->
    <div 
      v-show="isBoxSelecting"
      class="selection-box"
      :style="{
        left: `${selectionBox.left}px`,
        top: `${selectionBox.top}px`,
        width: `${selectionBox.width}px`,
        height: `${selectionBox.height}px`
      }"
    ></div>

    <div class="layout-container">
      <!-- header -->
      <el-header class="header" height="auto">
        <el-row class="header-left">
          <el-col :span="18">
            <el-row>
              <el-col style="display: flex;">
                <span style="display: flex; align-items: center; font-size: 20px;font-weight: bold;">云盘首页</span>
                <el-menu mode="horizontal" class="header-menu">
                  <el-menu-item index="1">
                    <el-icon><Folder /></el-icon>
                    <span>我的文件</span>
                  </el-menu-item>
                  <el-menu-item index="2">
                    <el-icon><Share /></el-icon>
                    <span>共享文件</span>
                  </el-menu-item>
                  <el-menu-item index="3">
                    <el-icon><Delete /></el-icon>
                    <span>回收站</span>
                  </el-menu-item>
                </el-menu>
              </el-col>
            </el-row>
          </el-col>
          <el-col :span="6" class="search-input-wrapper">
            <el-input
              placeholder="搜索文件"
              class="search-input"
              v-model="searchQuery"
            />
          </el-col>
        </el-row>
      </el-header>

      <!-- main content -->
      <div class="main-wrapper">
        <el-main class="main-content">
          <!-- 顶部操作栏 -->
          <div class="operation-bar">
            <div class="left-operations">
              <el-button-group>
                <el-button type="primary" @click="uploadFile">上传</el-button>
                <el-button type="primary" @click="createFolder">新建文件夹</el-button>
                <!-- 添加批量删除按钮 -->
                <el-button 
                  type="danger" 
                  @click="deleteSelectedFiles"
                  :disabled="selectedFiles.length === 0"
                >
                  批量删除
                </el-button>
              </el-button-group>
              <!-- 显示选中数量 -->
              <span v-if="selectedFiles.length > 0" class="selected-count">
                已选择 {{ selectedFiles.length }} 项
              </span>
            </div>
            <div class="right-operations">
              <!-- 添加筛选按钮 -->
              <el-select v-model="filterType" class="filter-select">
                <el-option label="全部" value="all" />
                <el-option label="文件夹" value="folder" />
                <el-option label="文件" value="file" />
              </el-select>
              
              <!-- 添加排序按钮组 -->
              <el-button-group class="sort-buttons">
                <el-button 
                  :type="sortBy === 'name' ? 'primary' : ''" 
                  @click="handleSortChange('name')"
                >
                  名称
                  <el-icon v-if="sortBy === 'name'">
                    <CaretTop v-if="sortOrder === 'asc'" />
                    <CaretBottom v-else />
                  </el-icon>
                </el-button>
                <el-button 
                  :type="sortBy === 'date' ? 'primary' : ''" 
                  @click="handleSortChange('date')"
                >
                  日期
                  <el-icon v-if="sortBy === 'date'">
                    <CaretTop v-if="sortOrder === 'asc'" />
                    <CaretBottom v-else />
                  </el-icon>
                </el-button>
                <el-button 
                  :type="sortBy === 'size' ? 'primary' : ''" 
                  @click="handleSortChange('size')"
                >
                  大小
                  <el-icon v-if="sortBy === 'size'">
                    <CaretTop v-if="sortOrder === 'asc'" />
                    <CaretBottom v-else />
                  </el-icon>
                </el-button>
              </el-button-group>

            <!-- 视图切换按钮 -->
            <el-button @click="toggleView">
              <el-icon><Grid v-if="isListView" /><List v-else /></el-icon>
              {{ isListView ? '图标展示' : '列表展示' }}
            </el-button>
          </div>
        </div>

          <!-- 文件路径导航 -->
          <el-breadcrumb separator="/" class="path-nav">
            <el-breadcrumb-item 
              v-for="(item, index) in currentPath" 
              :key="item.id"
              @click="handleBreadcrumbClick(item, index)"
              :class="{ 'breadcrumb-link': true }"
            >
              {{ item.name }}
            </el-breadcrumb-item>
          </el-breadcrumb>

          <!-- 文件列表 -->
          <div v-if="isListView" class="file-list">
            <el-table 
              ref="tableRef"
              :data="filteredFiles" 
              style="width: 100%"
              @selection-change="handleSelectionChange"
              @row-dblclick="handleDoubleClick"
            >
              <!-- 添加选择列 -->
              <el-table-column 
                type="selection" 
                width="55"
                @select-all="handleSelectAll"
              />
              <el-table-column label="文件名" min-width="400">
                <template #default="{ row }">
                  <div 
                    class="file-name-cell"
                    :data-file-id="row.id"
                    @contextmenu="(e) => handleContextMenu(e, row)"
                  >
                    <el-icon size="20">
                      <Folder v-if="row.type === 'folder'" />
                      <Document v-else />
                    </el-icon>
                    <span>{{ row.name }}</span>
                  </div>
                </template>
              </el-table-column>
              <el-table-column prop="size" label="大小" width="120" />
              <el-table-column prop="date" label="修改日期" width="180" />
              <el-table-column label="操作" width="150">
                <template #default="scope">
                  <el-button-group>
                    <el-button size="small" @click="downloadFile(scope.row)">下载</el-button>
                    <el-button size="small" type="danger" @click="deleteFile(scope.row)">删除</el-button>
                  </el-button-group>
                </template>
              </el-table-column>
            </el-table>
          </div>

          <!-- 网格视图 -->
          <div v-else class="grid-view">
            <div 
              v-for="file in filteredFiles" 
              :key="file.id" 
              class="file-item"
              :data-file-id="file.id"
              :class="{ 'is-selected': selectedFiles.includes(file) }"
              @dblclick="handleDoubleClick(file)"
              @contextmenu="(e) => handleContextMenu(e, file)"
            >
              <el-card :body-style="{ padding: '10px' }" shadow="hover">
                 <!-- 添加选择框 -->
                <div class="select-checkbox">
                  <el-checkbox 
                    v-model="selectedFiles"
                    :value="file"
                    @click.stop
                  />
                </div>
                <div class="file-icon">
                  <el-icon size="40">
                    <Folder v-if="file.type === 'folder'" />
                    <Document v-else />
                  </el-icon>
                </div>
                <div class="file-name">{{ file.name }}</div>
                <div class="file-info">
                  <span>{{ file.size }}</span>
                  <span>{{ file.date }}</span>
                </div>
              </el-card>
            </div>
          </div>
        </el-main>
      </div>
    </div>
    <!-- 新建文件夹对话框 -->
    <el-dialog
      v-model="newFolderDialogVisible"
      title="新建文件夹"
      width="30%"
    >
      <el-input
        v-model="newFolderName"
        placeholder="请输入文件夹名称"
        @keyup.enter="confirmCreateFolder"
      />
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="newFolderDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="confirmCreateFolder">确定</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 右键菜单 -->
    <div 
      v-show="contextMenuVisible"
      class="context-menu"
      :style="{
        left: contextMenuPosition.x + 'px',
        top: contextMenuPosition.y + 'px'
      }"
    >
      <!-- 文件/文件夹的右键菜单 -->
      <template v-if="selectedFile">
        <div 
          class="context-menu-item"
          @click="handleMenuAction('open')"
          v-if="selectedFile?.type === 'folder'"
        >
          <el-icon><FolderOpened /></el-icon>
          <span>打开</span>
        </div>
        <div 
          class="context-menu-item"
          @click="handleMenuAction('download')"
          v-if="selectedFile?.type === 'file'"
        >
          <el-icon><Download /></el-icon>
          <span>下载</span>
        </div>
        <div 
          class="context-menu-item"
          @click="handleMenuAction('rename')"
        >
          <el-icon><EditPen /></el-icon>
          <span>重命名</span>
        </div>
        <div 
          class="context-menu-item delete"
          @click="handleMenuAction('delete')"
        >
          <el-icon><Delete /></el-icon>
          <span>删除</span>
        </div>
      </template>

      <!-- 空白区域的右键菜单 -->
      <template v-else>
        <div 
          class="context-menu-item"
          @click="handleMenuAction('upload')"
        >
          <el-icon><Upload /></el-icon>
          <span>上传文件</span>
        </div>
        <div 
          class="context-menu-item"
          @click="handleMenuAction('newFolder')"
        >
          <el-icon><FolderAdd /></el-icon>
          <span>新建文件夹</span>
        </div>
        <div 
          class="context-menu-item"
          @click="handleMenuAction('refresh')"
        >
          <el-icon><Refresh /></el-icon>
          <span>刷新</span>
        </div>
      </template>
    </div>

    <!-- 重命名对话框 -->
    <el-dialog
      v-model="renameDialogVisible"
      title="重命名"
      width="30%"
    >
      <el-input
        v-model="newFileName"
        placeholder="请输入新名称"
        @keyup.enter="confirmRename"
      />
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="renameDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="confirmRename()">确定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 添加预览对话框 -->
    <el-dialog
      v-model="previewDialogVisible"
      :title="previewTitle"
      width="80%"
      :fullscreen="previewType === 'video'"
      destroy-on-close
    >
      <!-- 图片预览 -->
      <img
        v-if="previewType === 'image'"
        :src="previewUrl"
        class="preview-image"
        alt="预览图片"
      >
      
      <!-- PDF预览 -->
      <iframe
        v-else-if="previewType === 'pdf'"
        :src="previewUrl"
        class="preview-pdf"
      ></iframe>
      
      <!-- 视频预览 -->
      <video
        v-else-if="previewType === 'video'"
        :src="previewUrl"
        class="preview-video"
        controls
        autoplay
      ></video>
      
      <!-- 音频预览 -->
      <audio
        v-else-if="previewType === 'audio'"
        :src="previewUrl"
        class="preview-audio"
        controls
      ></audio>
      
      <!-- 文本预览 -->
      <div
        v-else-if="previewType === 'text'"
        class="preview-text-wrapper"
      >
        <el-scrollbar>
          <pre class="preview-text">{{ previewContent }}</pre>
        </el-scrollbar>
      </div>
    </el-dialog>

    <!-- 上传进度对话框 - 右上角 -->
    <div v-if="uploadFiles.length > 0" class="upload-progress-dialog">
      <div class="upload-header" @click="toggleUploadDetails">
        <span>文件上传中 ({{ completedCount }}/{{ uploadFiles.length }})</span>
        <el-icon :class="{ 'is-reverse': showUploadDetails }"><ArrowDown /></el-icon>
      </div>
      
      <!-- 上传详情面板 -->
      <div v-show="showUploadDetails" class="upload-details">
        <div v-for="file in uploadFiles" :key="file.name" class="upload-item">
          <div class="upload-info">
            <el-icon v-if="file.status === 'success'"><CircleCheck /></el-icon>
            <el-icon v-else-if="file.status === 'error'" class="error"><CircleClose /></el-icon>
            <span :class="{ 'success': file.status === 'success', 'error': file.status === 'error' }">
              {{ file.name }}
            </span>
          </div>
          <el-progress 
            :percentage="file.progress" 
            :status="file.status === 'error' ? 'exception' : file.status === 'success' ? 'success' : ''"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, defineExpose } from 'vue';
import { ElMessage, ElMessageBox  } from 'element-plus';
import * as FileAPI from '@/api/file';
import * as FolderAPI from '@/api/folder';
import { 
  Document, 
  Folder, 
  Delete, 
  Share,
  Grid,
  List,
  Upload,
  CaretTop,
  CaretBottom,
  FolderOpened,
  FolderAdd,
  Refresh,
  ArrowDown,
  CircleCheck,
  CircleClose,
  EditPen,
} from '@element-plus/icons-vue';
import UploadProgressDialog from './components/UploadProgressDialog.vue';

interface FolderItem {
  id: number;
  folder_name: string;
  created_at: string;
  subfolder_count: number;
  file_count: number;
}

interface FileItem {
  id: number;
  filename: string;
  file_size: number;
  upload_time: string;
  folder_id: number | null;
}

interface FolderResponse {
  files: FileItem[];
  folders: FolderItem[];
  success: boolean;
}

// 修改 fileList 的初始数据，添加 id 和 parentId
const fileList = ref<FileItem[]>([
]);
// 模拟用户ID（实际应该从登录状态获取）
const currentUserId = ref('1');
const loading = ref(false);
// 获取当前文件夹内容
const fetchFolderContents = async () => {
  try {
    loading.value = true;
    let response;
    
    // 根据是否有当前文件夹ID来决定调用哪个API
    if (currentFolderId.value) {
      // 获取特定文件夹的内容
      response = await FolderAPI.getFolderContents(currentFolderId.value, currentUserId.value);
    } else {
      // 获取根文件夹内容
      response = await FolderAPI.getRootFolders(currentUserId.value);
    }
    
    // 确保 response.folders 和 response.files 存在
    const folders = response.folders || [];
    const files = response.files || [];
    
    // 合并文件夹和文件列表
    fileList.value = [
      ...folders.map((folder: FolderItem) => ({
        id: folder.id.toString(),
        name: folder.folder_name,
        type: 'folder',
        size: '-',
        date: new Date(folder.created_at).toLocaleString(),
        parentId: currentFolderId.value,
        subfolder_count: folder.subfolder_count,
        file_count: folder.file_count
      })),
      ...files.map((file: FileItem) => ({
        id: file.id.toString(),
        name: file.filename,
        type: 'file',
        size: formatFileSize(file.file_size),
        date: new Date(file.upload_time).toLocaleString(),
        parentId: file.folder_id?.toString() || null
      }))
    ];
  } catch (error) {
    console.error('Error in fetchFolderContents:', error);
    ElMessage.error(typeof error === 'string' ? error : '获取文件夹内容失败');
  } finally {
    loading.value = false;
  }
};

// 格式化文件大小
const formatFileSize = (bytes: number) => {
  if (bytes === 0) return '0 B';
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};

// 上传文件
const handleFileUpload = async (file: File) => {
  try {
    loading.value = true;
    await FileAPI.uploadFile(file, currentUserId.value);
    ElMessage.success('上传成功');
    fetchFolderContents();
  } catch (error) {
    ElMessage.error(typeof error === 'string' ? error : '上传失败');
  } finally {
    loading.value = false;
  }
};
// 当前文件夹ID
const currentFolderId = ref<string | null>(null);

// 当前路径
const currentPath = ref<{ id: string; name: string }[]>([{ id: 'root', name: '全部文件' }]);

const searchQuery = ref('');
const isListView = ref(true);

// 过滤显示当前文件夹的文件
const filteredFiles = computed(() => {
  let files = fileList.value
  
  // 应用搜索过滤
  if (searchQuery.value) {
    files = files.filter(file => 
      file.name.toLowerCase().includes(searchQuery.value.toLowerCase())
    );
  }

  // 应用类型过滤
  if (filterType.value !== 'all') {
    files = files.filter(file => file.type === filterType.value);
  }

  // 应用排序
  return files.sort((a, b) => {
    let compareResult = 0;
    
    // 在 switch 语句外声明变量
    const sizeA = parseFileSize(a.size);
    const sizeB = parseFileSize(b.size);
    
    switch (sortBy.value) {
      case 'name':
        compareResult = a.name.localeCompare(b.name);
        break;
      case 'date':
        compareResult = new Date(b.date).getTime() - new Date(a.date).getTime();
        break;
      case 'size':
        // 文件夹始终排在前面
        if (a.type === 'folder' && b.type !== 'folder') return -1;
        if (a.type !== 'folder' && b.type === 'folder') return 1;
        // 使用预先声明的变量比较文件大小
        compareResult = sizeA - sizeB;
        break;
    }

    return sortOrder.value === 'asc' ? compareResult : -compareResult;
  });
});

const toggleView = () => {
  isListView.value = !isListView.value;
};

const uploadFile = () => {
  // 创建隐藏的文件输入框
  const input = document.createElement('input');
  input.type = 'file';
  input.multiple = true; // 允许多文件选择
  input.style.display = 'none';
  input.onchange = handleFileSelect;
  document.body.appendChild(input);
  input.click();
  document.body.removeChild(input);
};

// 创建文件夹
const createFolder = () => {
  // 实现创建文件夹逻辑
  newFolderName.value = '新建文件夹';
  newFolderDialogVisible.value = true;
};
// 下载文件
const downloadFile = async (file: any) => {
  try {
    loading.value = true;
    let response;
    
    if (file.type === 'folder') {
      response = await FolderAPI.downloadFolder(file.id, currentUserId.value);
    } else {
      response = await FileAPI.downloadFile(file.id);
    }
    
    // 创建下载链接
    const url = window.URL.createObjectURL(new Blob([response]));
    const link = document.createElement('a');
    link.href = url;
    // 根据类型设置不同的文件扩展名
    const extension = file.type === 'folder' ? '.zip' : '';
    link.setAttribute('download', file.name + extension);
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    window.URL.revokeObjectURL(url);
    
    ElMessage.success('下载成功');
  } catch (error) {
    ElMessage.error(typeof error === 'string' ? error : '下载失败');
  } finally {
    loading.value = false;
  }
};

// 删除文件
const deleteFile = async (file: any) => {
  try {
    await ElMessageBox.confirm(
      '确定要删除该文件吗？',
      '删除确认',
      { type: 'warning' }
    );
    
    loading.value = true;
    if (file.type === 'folder') {
      await FolderAPI.deleteFolder(file.id, currentUserId.value);
    } else {
      await FileAPI.deleteFile(file.id);
    }
    ElMessage.success('删除成功');
    fetchFolderContents();
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error(typeof error === 'string' ? error : '删除失败');
    }
  } finally {
    loading.value = false;
  }
};

// 拖拽相关的状态
const isDragging = ref(false);
const uploadDialogVisible = ref(false);
const uploadFiles = ref<Array<{ name: string; progress: number }>>([]);

// 处理拖拽事件
const handleDragOver = (e: DragEvent) => {
  isDragging.value = true;
  e.dataTransfer!.dropEffect = 'copy';
};

const handleDragLeave = (e: DragEvent) => {
  // 确保鼠标真的离开了整个区域
  const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();
  const x = e.clientX;
  const y = e.clientY;
  
  if (x <= rect.left || x >= rect.right || y <= rect.top || y >= rect.bottom) {
    isDragging.value = false;
  }
};

const handleDrop = async (e: DragEvent) => {
  isDragging.value = false;
  const items = Array.from(e.dataTransfer!.items);
  
  // 检查是否有文件夹被拖拽
  const files = items.map(item => item.getAsFile()).filter(file => file);
  const folders = items.filter(item => item.kind === 'file' && item.webkitGetAsEntry().isDirectory);

  // 处理文件夹上传
  if (folders.length > 0) {
    for (const folder of folders) {
      const folderEntry = folder.webkitGetAsEntry();
      if (folderEntry) {
        await uploadFolderContents(folderEntry, currentFolderId.value);
      }
    }
  }

  // 处理文件上传
  if (files.length > 0) {
    // 显示上传对话框
    uploadDialogVisible.value = true;
    
    // 初始化上传文件列表
    uploadFiles.value = files.map(file => ({
      name: file.name,
      progress: 0
    }));

    try {
      loading.value = true;
      // 传入当前文件夹ID
      await FileAPI.uploadMultipleFiles(files, currentUserId.value, currentFolderId.value);
      ElMessage.success('文件上传成功');
      fetchFolderContents(); // 刷新文件列表
    } catch (error) {
      ElMessage.error(typeof error === 'string' ? error : '文件上传失败');
    } finally {
      loading.value = false;
      uploadDialogVisible.value = false;
    }
  }
};

// 上传文件夹内容
const uploadFolderContents = async (folderEntry: any, parentFolderId: string | null) => {
  try {
    console.log('开始上传文件夹:', folderEntry.name);
    const newFolderName = folderEntry.name;
    
    // 创建新文件夹
    let newFolderId;
    try {
      newFolderId = await createNewFolder(newFolderName, parentFolderId);
      console.log('创建文件夹成功, ID:', newFolderId);
    } catch (error) {
      console.error('创建文件夹失败:', error);
      ElMessage.error(`创建文件夹 ${newFolderName} 失败`);
      throw error;
    }

    const reader = folderEntry.createReader();
    const files: File[] = [];
    
    // 读取文件夹内容
    const readEntries = async () => {
      return new Promise<void>((resolve, reject) => {
        const readNextBatch = () => {
          reader.readEntries(async (entries: any[]) => {
            try {
              if (entries.length === 0) {
                resolve();
                return;
              }

              for (const entry of entries) {
                if (entry.isFile) {
                  try {
                    const file = await new Promise<File>((resolve, reject) => {
                      entry.file(resolve, reject);
                    });
                    files.push(file);
                    console.log('添加文件:', file.name);
                  } catch (error) {
                    console.error('读取文件失败:', error);
                  }
                } else if (entry.isDirectory) {
                  try {
                    await uploadFolderContents(entry, newFolderId);
                    console.log('处理子文件夹:', entry.name);
                  } catch (error) {
                    console.error('处理子文件夹失败:', error);
                  }
                }
              }
              
              // 继续读取下一批
              readNextBatch();
            } catch (error) {
              console.error('处理文件夹内容失败:', error);
              reject(error);
            }
          }, (error: any) => {
            console.error('读取文件夹条目失败:', error);
            reject(error);
          });
        };
        
        readNextBatch();
      });
    };

    await readEntries();
    console.log(`文件夹 ${newFolderName} 中找到 ${files.length} 个文件`);

    // 上传文件
    if (files.length > 0) {
      try {
        console.log(`开始上传文件到文件夹 ${newFolderId}`);
        console.log('文件列表:', files.map(f => f.name));
        
        // 分批上传文件
        const batchSize = 12; // 每批上传的文件数量
        const totalBatches = Math.ceil(files.length / batchSize);
        
        for (let i = 0; i < files.length; i += batchSize) {
          const batch = files.slice(i, i + batchSize);
          const currentBatch = Math.floor(i / batchSize) + 1;
          
          try {
            console.log(`开始上传第 ${currentBatch}/${totalBatches} 批，包含 ${batch.length} 个文件`);
            console.log('当前批次文件:', batch.map(f => f.name));
            
            // 创建新的 FormData 对象
            const formData = new FormData();
            batch.forEach(file => {
              formData.append('files', file);
            });
            formData.append('userId', currentUserId.value);
            formData.append('folderId', newFolderId);
            
            // 上传当前批次
            await FileAPI.uploadMultipleFiles(batch, currentUserId.value, newFolderId);
            
            console.log(`批次 ${currentBatch}/${totalBatches} 上传成功`);
            ElMessage.success(`文件夹 ${newFolderName} 批次 ${currentBatch}/${totalBatches} 上传成功`);
            
            // 添加延迟，避免服务器压力
            if (currentBatch < totalBatches) {
              await new Promise(resolve => setTimeout(resolve, 1000));
            }
          } catch (error) {
            console.error(`批次 ${currentBatch}/${totalBatches} 上传失败:`, error);
            ElMessage.error(`批次 ${currentBatch}/${totalBatches} 上传失败: ${error.message || '未知错误'}`);
            
            // 重试当前批次
            try {
              console.log(`尝试重新上传批次 ${currentBatch}/${totalBatches}`);
              await FileAPI.uploadMultipleFiles(batch, currentUserId.value, newFolderId);
              console.log(`批次 ${currentBatch}/${totalBatches} 重试上传成功`);
              ElMessage.success(`文件夹 ${newFolderName} 批次 ${currentBatch}/${totalBatches} 重试上传成功`);
            } catch (retryError) {
              console.error(`批次 ${currentBatch}/${totalBatches} 重试上传失败:`, retryError);
              ElMessage.error(`批次 ${currentBatch}/${totalBatches} 重试上传失败: ${retryError.message || '未知错误'}`);
              throw retryError;
            }
          }
        }
      } catch (error) {
        console.error('上传文件失败:', error);
        ElMessage.error(`上传文件到文件夹 ${newFolderName} 失败: ${error.message || '未知错误'}`);
        throw error;
      }
    } else {
      console.log(`文件夹 ${newFolderName} 为空`);
    }
  } catch (error) {
    console.error('处理文件夹失败:', error);
    ElMessage.error(`处理文件夹 ${folderEntry.name} 失败: ${error.message || '未知错误'}`);
    throw error;
  }
};

// 创建新文件夹并返回其ID
const createNewFolder = async (folderName: string, parentId: string | null) => {
  try {
    loading.value = true;
    const response = await FolderAPI.createFolder({
      folderName,
      parentId: parentId || currentFolderId.value, // 使用传入的父文件夹ID
      userId: currentUserId.value
    });
    return response.folderId; // 假设API返回新创建文件夹的ID
  } catch (error) {
    ElMessage.error(typeof error === 'string' ? error : '创建文件夹失败');
    throw error; // 重新抛出错误以便处理
  } finally {
    loading.value = false;
  }
};

// 处理文件选择上传
const handleFileSelect = async (e: Event) => {
  const input = e.target as HTMLInputElement;
  if (!input.files?.length) return;

  const files = Array.from(input.files);
  
  // 显示上传对话框
  uploadDialogVisible.value = true;
  
  // 初始化上传文件列表
  uploadFiles.value = files.map(file => ({
    name: file.name,
    progress: 0
  }));

  try {
    loading.value = true;
    // 传入当前文件夹ID
    await FileAPI.uploadMultipleFiles(files, currentUserId.value, currentFolderId.value);
    ElMessage.success('文件上传成功');
    fetchFolderContents();
  } catch (error) {
    ElMessage.error(typeof error === 'string' ? error : '文件上传失败');
  } finally {
    loading.value = false;
    uploadDialogVisible.value = false;
    // 清空 input 的值，允许重复上传相同文件
    input.value = '';
  }
};
// 模拟文件上传进度
const simulateFileUpload = (fileIndex: number) => {
  return new Promise((resolve) => {
    let progress = 0;
    const interval = setInterval(() => {
      progress += 10;
      uploadFiles.value[fileIndex].progress = progress;
      
      if (progress >= 100) {
        clearInterval(interval);
        resolve(true);
      }
    }, 200);
  });
};

// 处理面包屑导航点击
const handleBreadcrumbClick = (pathItem: { id: string; name: string }, index: number) => {
  currentFolderId.value = pathItem.id === 'root' ? null : pathItem.id;
  currentPath.value = currentPath.value.slice(0, index + 1);
  fetchFolderContents();
};
// 新建文件夹相关状态
const newFolderDialogVisible = ref(false);
const newFolderName = ref('新建文件夹');
const folderCount = ref(1);

// 修改创建文件夹方法
const confirmCreateFolder = async () => {
  if (!newFolderName.value.trim()) {
    ElMessage.warning('文件夹名称不能为空');
    return;
  }

  const isExist = fileList.value.some(
    file => file.parentId === currentFolderId.value && file.name === newFolderName.value
  );
  
  if (isExist) {
    ElMessage.warning('文件夹名称已存在');
    return;
  }

  try {
    loading.value = true;
    await FolderAPI.createFolder({
      folderName: newFolderName.value,
      parentId: currentFolderId.value,
      userId: currentUserId.value
    });
    
    ElMessage.success('文件夹创建成功');
    newFolderDialogVisible.value = false;
    // 刷新文件夹内容
    fetchFolderContents();
  } catch (error) {
    ElMessage.error(typeof error === 'string' ? error : '创建文件夹失败');
  } finally {
    loading.value = false;
  }
};

// 右键菜单相关状态
const contextMenuVisible = ref(false);
const contextMenuPosition = ref({ x: 0, y: 0 });
const selectedFile = ref<FileItem | null>(null);
const renameDialogVisible = ref(false);
const newFileName = ref('');

// 处理右键菜单点击
const handleContextMenu = (e: MouseEvent, file: FileItem) => {
  e.preventDefault();
  contextMenuPosition.value = {
    x: e.clientX,
    y: e.clientY
  };
  selectedFile.value = file;
  contextMenuVisible.value = true;
};

// 关闭右键菜单
const closeContextMenu = () => {
  contextMenuVisible.value = false;
};

// 处理菜单项点击
const handleMenuAction = async (action: string) => {
  if (selectedFile.value) {
    // 处理文件/文件夹的菜单操作
    switch (action) {
      case 'open':
        if (selectedFile.value.type === 'folder') {
          handleDoubleClick(selectedFile.value);
        }
        break;
      case 'download':
        await downloadFile(selectedFile.value);
        break;
      case 'delete':
        await deleteFile(selectedFile.value);
        break;
      case 'rename':
        startRename(selectedFile.value);
        break;
    }
  } else {
    // 处理空白区域的菜单操作
    switch (action) {
      case 'upload':
        uploadFile();
        break;
      case 'newFolder':
        createFolder();
        break;
      case 'refresh':
        fetchFolderContents();
        ElMessage.success('刷新成功');
        break;
    }
  }
  closeContextMenu();
};

// 开始重命名
const startRename = (file: any) => {
  selectedFile.value = file;
  newFileName.value = file.name;
  renameDialogVisible.value = true;
};

// 确认重命名
const confirmRename = async () => {
  if (!selectedFile.value) {
    ElMessage.warning('没有选中的文件');
    return;
  }
  
  if (!newFileName.value.trim()) {
    ElMessage.warning('文件名不能为空');
    return;
  }
  
  const isExist = fileList.value.some(
    file => 
      file.id !== selectedFile.value?.id && 
      file.parentId === selectedFile.value?.parentId && 
      file.name === newFileName.value
  );

  if (isExist) {
    ElMessage.warning('文件名已存在');
    return;
  }

  try {
    loading.value = true;
    if (selectedFile.value.type === 'folder') {
      await FolderAPI.renameFolder(
        selectedFile.value.id,
        newFileName.value,
        currentUserId.value
      );
    } else {
      await FileAPI.renameFile(
        selectedFile.value.id,
        newFileName.value,
        currentUserId.value
      );
    }

    ElMessage.success('重命名成功');
    renameDialogVisible.value = false;
    fetchFolderContents();
  } catch (error) {
    ElMessage.error(typeof error === 'string' ? error : '重命名失败');
  } finally {
    loading.value = false;
  }
};

// 排序相关状态
const sortBy = ref<'name' | 'date' | 'size'>('name');
const sortOrder = ref<'asc' | 'desc'>('asc');

// 筛选相关状态
const filterType = ref<'all' | 'folder' | 'file'>('all');

// 解析文件大小字符串为数字（字节）
const parseFileSize = (size: string): number => {
  if (size === '-') return 0;
  const units = { 'B': 1, 'KB': 1024, 'MB': 1024 * 1024, 'GB': 1024 * 1024 * 1024 };
  const matches = size.match(/^([\d.]+)\s*([KMGT]?B)$/i);
  if (!matches) return 0;
  const [, num, unit] = matches;
  return parseFloat(num) * (units[unit as keyof typeof units] || 0);
};

// 处理排序变化
const handleSortChange = (type: 'name' | 'date' | 'size') => {
  if (sortBy.value === type) {
    sortOrder.value = sortOrder.value === 'asc' ? 'desc' : 'asc';
  } else {
    sortBy.value = type;
    sortOrder.value = 'asc';
  }
};

// 添加选中文件相关状态
const selectedFiles = ref<FileItem[]>([]);

// 处理表格选择变化
const handleSelectionChange = (selection: any[]) => {
  if (!isBoxSelecting.value) {
    selectedFiles.value = selection;
  }
};

// 处理全选/取消全选
const handleSelectAll = (selection: FileItem[]) => {
  selectedFiles.value = selection;
};

// 批量删除
const deleteSelectedFiles = async () => {
  if (selectedFiles.value.length === 0) {
    ElMessage.warning('请选择要删除的文件');
    return;
  }

  try {
    await ElMessageBox.confirm(
      `确定要删除选中的 ${selectedFiles.value.length} 个文件吗？`,
      '删除确认',
      { type: 'warning' }
    );

    loading.value = true;
    for (const file of selectedFiles.value) {
      if (file.type === 'folder') {
        await FolderAPI.deleteFolder(file.id, currentUserId.value);
      } else {
        await FileAPI.deleteFile(file.id);
      }
    }
    
    ElMessage.success('删除成功');
    selectedFiles.value = [];
    fetchFolderContents();
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error(typeof error === 'string' ? error : '删除失败');
    }
  } finally {
    loading.value = false;
  }
};

// 分享文件
const shareFile = async (file: FileItem, sharedWithId: string) => {
  try {
    loading.value = true;
    await FileAPI.shareFile(file.id, currentUserId.value, sharedWithId);
    ElMessage.success('分享成功');
  } catch (error) {
    ElMessage.error(typeof error === 'string' ? error : '分享失败');
  } finally {
    loading.value = false;
  }
};

// 添加可预览文件类型判断
const PREVIEWABLE_EXTENSIONS = {
  // 图片文件
  image: ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp'],
  // 文本文件
  text: ['.txt', '.md', '.json', '.js', '.ts', '.html', '.css', '.vue'],
  // PDF文件
  pdf: ['.pdf'],
  // 视频文件
  video: ['.mp4', '.webm', '.ogg'],
  // 音频文件
  audio: ['.mp3', '.wav', '.ogg', '.m4a']
};

// 判断文件是否可预览
const isPreviewable = (filename: string): boolean => {
  const extension = filename.toLowerCase().substring(filename.lastIndexOf('.'));
  return Object.values(PREVIEWABLE_EXTENSIONS).some(exts => exts.includes(extension));
};

// 获取文件类型
const getFileType = (filename: string): string => {
  const extension = filename.toLowerCase().substring(filename.lastIndexOf('.'));
  // 根据扩展名判断文件类型
  if (['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp'].includes(extension)) {
    return 'image';
  } else if (['.txt', '.md', '.json', '.js', '.ts', '.html', '.css', '.vue'].includes(extension)) {
    return 'text';
  } else if (extension === '.pdf') {
    return 'pdf';
  } else if (['.mp4', '.webm', '.ogg'].includes(extension)) {
    return 'video';
  } else if (['.mp3', '.wav', '.m4a'].includes(extension)) {
    return 'audio';
  }
  return 'unknown';
};

// 添加预览对话框相关状态
const previewDialogVisible = ref(false);
const previewUrl = ref('');
const previewType = ref('');
const previewTitle = ref('');

// 修改双击处理事件
const handleDoubleClick = async (file: FileItem) => {
  if (file.type === 'folder') {
    currentFolderId.value = file.id;
    currentPath.value = [...currentPath.value, { id: file.id, name: file.name }];
    fetchFolderContents();
  } else {
    const fileType = getFileType(file.name);
    if (fileType !== 'unknown') {
      try {
        loading.value = true;
        previewType.value = fileType;
        previewTitle.value = file.name;
        
        // 直接使用 API URL 作为预览源
        previewUrl.value = `http://localhost:3000/api/files/preview/${file.id}?userId=${currentUserId.value}`;
        previewDialogVisible.value = true;
      } catch (error) {
        ElMessage.error('预览失败');
      } finally {
        loading.value = false;
      }
    } else {
      downloadFile(file);
    }
  }
};

// 修改框选状态的数据结构
const isBoxSelecting = ref(false);
const selectionBox = ref({
  startX: 0,
  startY: 0,
  currentX: 0,
  currentY: 0,
  left: 0,
  top: 0,
  width: 0,
  height: 0
});

// 修改框选相关方法
const startBoxSelection = (e: MouseEvent) => {
  // 检查是否点击在可选择区域
  const target = e.target as HTMLElement;
  if (target.closest('.file-item, .el-table__row, .operation-bar, .path-nav, .el-button, .el-menu-item')) {
    return;
  }

  // 获取相对于视口的坐标
  const { clientX, clientY } = e;
  
  isBoxSelecting.value = true;
  selectionBox.value = {
    startX: clientX,
    startY: clientY,
    currentX: clientX,
    currentY: clientY,
    left: clientX,
    top: clientY,
    width: 0,
    height: 0
  };
};

const updateBoxSelection = (e: MouseEvent) => {
  if (!isBoxSelecting.value) return;

  const { clientX, clientY } = e;
  selectionBox.value.currentX = clientX;
  selectionBox.value.currentY = clientY;

  // 计算选择框的位置和尺寸
  selectionBox.value.left = Math.min(selectionBox.value.startX, clientX);
  selectionBox.value.top = Math.min(selectionBox.value.startY, clientY);
  selectionBox.value.width = Math.abs(clientX - selectionBox.value.startX);
  selectionBox.value.height = Math.abs(clientY - selectionBox.value.startY);

  // 获取选择框的边界
  const { left, top, width, height } = selectionBox.value;
  const right = left + width;
  const bottom = top + height;

  // 修改选择器以更好地匹配列表视图
  const fileElements = isListView.value 
    ? document.querySelectorAll('.el-table__row') 
    : document.querySelectorAll('.file-item');
    
  const newSelectedFiles: any[] = [];

  fileElements.forEach((element) => {
    const rect = element.getBoundingClientRect();
    if (
      rect.left < right &&
      rect.right > left &&
      rect.top < bottom &&
      rect.bottom > top
    ) {
      // 针对列表视图和网格视图分别处理
      let fileId;
      if (isListView.value) {
        // 对于列表视图，从行数据中获取ID
        const rowData = fileList.value[Array.from(fileElements).indexOf(element)];
        fileId = rowData?.id;
      } else {
        // 对于网格视图，从data-file-id属性获取ID
        fileId = element.getAttribute('data-file-id');
      }
      
      const file = fileList.value.find(f => f.id === fileId);
      if (file) {
        newSelectedFiles.push(file);
      }
    }
  });

  selectedFiles.value = newSelectedFiles;
  
  // 更新表格选择状态
  if (isListView.value && tableRef.value) {
    // 清除现有选择
    tableRef.value.clearSelection();
    // 为每个选中的文件设置选中状态
    newSelectedFiles.forEach(file => {
      tableRef.value.toggleRowSelection(file, true);
    });
  }
};

const endBoxSelection = () => {
  if (!isBoxSelecting.value) return;
  isBoxSelecting.value = false;
};

// 添加清理事件监听
onMounted(() => {
  fetchFolderContents();
  document.addEventListener('click', closeContextMenu);
  document.addEventListener('mouseleave', endBoxSelection);
});

onUnmounted(() => {
  document.removeEventListener('click', closeContextMenu);
  document.removeEventListener('mouseleave', endBoxSelection);
});

// 添加表格引用
const tableRef = ref();

// 修改右键菜单处理方法
const handleEmptyAreaContextMenu = (e: MouseEvent) => {
  // 检查是否点击在空白区域
  const target = e.target as HTMLElement;
  if (target.closest('.file-item, .el-table__row, .operation-bar, .path-nav, .el-button, .el-menu-item')) {
    return;
  }

  // 显示空白区域的右键菜单
  contextMenuPosition.value = {
    x: e.clientX,
    y: e.clientY
  };
  selectedFile.value = null; // 清除选中的文件
  contextMenuVisible.value = true;
};

// 上传进度对话框相关状态
const uploadProgressRef = ref();
const showUploadDetails = ref(false);
const completedCount = computed(() => {
  return uploadFiles.value.filter(file => file.status === 'success').length;
});

// 切换上传详情显示
const toggleUploadDetails = () => {
  showUploadDetails.value = !showUploadDetails.value;
};

// 更新文件上传进度
const updateFileProgress = (fileName: string, progress: number) => {
  const file = uploadFiles.value.find(f => f.name === fileName);
  if (file) {
    file.progress = progress;
    if (progress === 100) {
      file.status = 'success';
      // 显示上传成功通知
      ElMessage({
        message: `文件 ${fileName} 上传成功`,
        type: 'success',
        duration: 3000
      });
    }
  }
};

// 添加上传文件
const addUploadFile = (fileName: string) => {
  uploadFiles.value.push({
    name: fileName,
    progress: 0,
    status: 'uploading'
  });
};

// 标记文件上传失败
const markFileError = (fileName: string) => {
  const file = uploadFiles.value.find(f => f.name === fileName);
  if (file) {
    file.status = 'error';
  }
};

// 清理已完成的文件
const clearCompletedFiles = () => {
  uploadFiles.value = uploadFiles.value.filter(file => file.status === 'uploading');
};

// 导出方法供其他组件使用
defineExpose({
  addUploadFile,
  updateFileProgress,
  markFileError,
  clearCompletedFiles
});
</script>

<style scoped lang="less">
.home {
  width: 100%;
  height: 100vh;
  position: relative;
}

.layout-container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.header {
  .search-input-wrapper{
    display: flex;
    justify-content: flex-end;
    align-items: center;
  }
}

.main-wrapper {
  flex: 1;
  position: relative;
  overflow: hidden;
}

.main-content {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  overflow-y: auto;
  background-color: #f5f5f5;
  padding: 20px;
}

.operation-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  background-color: #fff;
  padding: 16px;
  border-radius: 4px;
}

.path-nav {
  margin: 20px 0;
  background-color: #fff;
  padding: 16px;
  border-color: #fff;

  .breadcrumb-link {
    cursor: pointer;
    &:hover {
      color: var(--el-color-primary);
    }
  }
}

.file-name-cell {
  display: flex;
  align-items: center;
  gap: 8px;
}

.grid-view {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 20px;
  padding: 20px;
  background-color: #fff;
  border-radius: 4px;
}

.file-item {
  cursor: pointer;
}

.file-icon {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 80px;
}

.file-name {
  text-align: center;
  margin: 10px 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-info {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: #999;
}

.file-list {
  background-color: #fff;
  border-radius: 4px;
  padding: 16px;
}

:deep(.el-menu-item) {
  display: flex;
  align-items: center;
  gap: 8px;
}

:deep(.el-menu--horizontal > .el-menu-item) {
  border-bottom: none !important;
}

.drag-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(255, 255, 255, 0.9);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  z-index: 1000;

  .el-icon {
    color: var(--el-color-primary);
    margin-bottom: 16px;
  }

  p {
    font-size: 20px;
    color: var(--el-color-primary);
  }
}

.upload-item {
  margin-bottom: 16px;

  .upload-info {
    display: flex;
    justify-content: space-between;
    margin-bottom: 8px;

    span:last-child {
      color: var(--el-color-primary);
    }
  }
}

.context-menu {
  position: fixed;
  background: white;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 5px 0;
  min-width: 150px;
  box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
  z-index: 3000;

  .context-menu-item {
    padding: 8px 16px;
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    transition: background-color 0.3s;

    &:hover {
      background-color: var(--el-color-primary-light-9);
    }

    .el-icon {
      font-size: 16px;
    }

    &.delete {
      color: var(--el-color-danger);
      
      &:hover {
        background-color: var(--el-color-danger-light-9);
      }
    }
  }
}

.file-name-cell, .file-item {
  user-select: none;
}

.operation-bar {
  .right-operations {
    display: flex;
    gap: 12px;
    align-items: center;

    .filter-select {
      width: 120px;
    }

    .sort-buttons {
      .el-button {
        display: flex;
        align-items: center;
        gap: 4px;
      }
    }
  }
}
.operation-bar {
  .left-operations {
    display: flex;
    align-items: center;
    gap: 12px;

    .selected-count {
      color: var(--el-color-primary);
      font-size: 14px;
    }
  }
}

.grid-view {
  .file-item {
    position: relative;
    
    .select-checkbox {
      position: absolute;
      top: 8px;
      left: 8px;
      z-index: 1;
    }

    &.is-selected {
      :deep(.el-card) {
        border-color: var(--el-color-primary);
        background-color: var(--el-color-primary-light-9);
      }
    }
  }
}

.file-name-cell {
  user-select: none;
}

.preview-image {
  max-width: 100%;
  max-height: 70vh;
  display: block;
  margin: 0 auto;
}

.preview-pdf {
  width: 100%;
  height: 70vh;
  border: none;
}

.preview-video {
  width: 100%;
  max-height: 70vh;
}

.preview-audio {
  width: 100%;
}

.preview-text {
  width: 100%;
  max-height: 70vh;
  overflow: auto;
  white-space: pre-wrap;
  word-wrap: break-word;
  padding: 16px;
  background-color: #f5f5f5;
  border-radius: 4px;
}

.selection-box {
  position: fixed;
  border: 2px solid var(--el-color-primary);
  background-color: rgba(var(--el-color-primary-rgb), 0.1);
  pointer-events: none;
  z-index: 2000;
}

// 确保文件项可以被正确选中
.file-item {
  position: relative;
  z-index: 1;
  
  &.is-selected {
    z-index: 2;
  }
}

.el-table__row {
  position: relative;
  z-index: 1;
  
  &.is-selected {
    z-index: 2;
  }
}

.upload-progress-dialog {
  position: fixed;
  right: 20px;
  top: 20px;
  width: 300px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  z-index: 2000;
}

.upload-header {
  padding: 12px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  cursor: pointer;
  border-bottom: 1px solid #eee;
}

.upload-header:hover {
  background: #f5f7fa;
}

.upload-details {
  max-height: 300px;
  overflow-y: auto;
  padding: 12px;
}

.upload-item {
  margin-bottom: 12px;
}

.upload-info {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
}

.upload-info .el-icon {
  margin-right: 8px;
}

.upload-info .success {
  color: #67c23a;
}

.upload-info .error {
  color: #f56c6c;
}

.is-reverse {
  transform: rotate(180deg);
}
</style>